﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;

namespace Web.Menus
{
    /// <summary>
    /// 菜单帮助类
    /// </summary>
    public static class MenuHelper
    {
        /// <summary>
        /// 缓存数据
        /// </summary>
        private static Menu[] _menuCached;

        /// <summary>
        /// 获取所有菜单信息
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="subMenuName">要激活的子单名的名称或连接</param>
        /// <returns></returns>
        public static Menu[] GetAllMenus(UrlHelper helper, string activeSubMenu)
        {
            var controller = helper.RequestContext.RouteData.Values["controller"].ToString();
            var action = helper.RequestContext.RouteData.Values["action"].ToString();
            var link = helper.Action(action, controller).ToLower();

            Menu[] menus = GetMenus(helper);
            Menu subMenu = null;

            if (string.IsNullOrEmpty(activeSubMenu) == false)
            {
                subMenu = menus.SelectMany(item => item.SubMenus).FirstOrDefault(item => item.Name == activeSubMenu || item.Link.Contains(activeSubMenu.ToLower()));
            }
            if (subMenu == null)
            {
                subMenu = menus.SelectMany(item => item.SubMenus).FirstOrDefault(item => item.Link == link);
            }
            if (subMenu == null)
            {
                var menu = menus.FirstOrDefault(item => item.Link == link);
                if (menu == null)
                {
                    menu = menus.FirstOrDefault();
                }
                if (menu != null)
                {
                    menu.IsActive = true;
                }
            }
            else
            {
                subMenu.IsActive = true;
                subMenu.ParentMenu.IsActive = true;
            }
            return menus;
        }

        /// <summary>
        /// 反射获取菜单信息
        /// </summary>
        /// <param name="helper"></param>
        /// <returns></returns>
        private static Menu[] GetMenus(UrlHelper helper)
        {
            if (_menuCached != null)
            {
                foreach (var item in _menuCached)
                {
                    item.IsActive = false;
                    foreach (var sub in item.SubMenus)
                    {
                        sub.IsActive = false;
                    }
                }
                return _menuCached;
            }

            var fileds = typeof(MenuConfig).GetFields(BindingFlags.Static | BindingFlags.Public);
            var menus = fileds.Select(item =>
            {
                var attributes = Attribute.GetCustomAttributes(item, typeof(MenuAttribute)) as MenuAttribute[];
                var menuAttribute = attributes.FirstOrDefault(m => m.GetType() == typeof(MenuAttribute));
                var subMenuAttribute = attributes.Except(new[] { menuAttribute }).Cast<SubMenuAttribute>();

                var menu = menuAttribute.ToMenu(helper);
                menu.SubMenus = subMenuAttribute.OrderBy(s => s.Index).Select(s => s.ToMenu(helper)).ToArray();
                foreach (var sub in menu.SubMenus)
                {
                    sub.ParentMenu = menu;
                }
                return menu;
            }).ToArray();

            _menuCached = menus;
            return _menuCached;
        }
    }
}